﻿using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.IO;
using System.Linq;
using System.Security.Cryptography;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;

namespace OfflineAuthorization
{
    public partial class FrmLicenseGenerator : Form
    {
        public FrmLicenseGenerator()
        {
            InitializeComponent();
        }



        string serialNo = string.Empty;
        private void btnGenSN_Click(object sender, EventArgs e)
        {
            var sn = LicenseTools.LicenseClient.GenSerialNo();
            if(sn==null)
            {
                MessageBox.Show("生成机器序列号失败！", "提示");
                return;
            }
            serialNo = sn;
            tbSN.Text = sn;
        }

        private void btnGenKey_Click(object sender, EventArgs e)
        {
            var key = LicenseTools.LicenseServer.GenXmlKey();
            if(key == null) 
            {
                MessageBox.Show("生成密钥失败！", "提示");
                return;
            }

            try
            {
                //写入文件
                using (FolderBrowserDialog dialog = new FolderBrowserDialog())
                {
                    if (dialog.ShowDialog() == DialogResult.OK)
                    {
                        string savePath = dialog.SelectedPath;
                        using (StreamWriter writer = new StreamWriter(Path.Combine(savePath, "PublicKey.xml")))
                        {
                            writer.WriteLine(key[0]);
                        }
                        using (StreamWriter writer = new StreamWriter(Path.Combine(savePath, "PrivateKey.xml")))
                        {
                            writer.WriteLine(key[1]);
                        }
                    }
                    else
                        return;
                }
            }
            catch (Exception)
            {

                MessageBox.Show("保存密钥失败！","提示");
            }


            //配置公私钥
            publicKey = key[0];
            tbPubKey.Text = key[0];

            privateKey = key[1];
            tbPriKey.Text = key[1];
        }


        //公私钥
        string privateKey = string.Empty;
        string publicKey = string.Empty;


        private void btnSetPublicKey_Click(object sender, EventArgs e)
        {
            try
            {
                using (OpenFileDialog dialog = new OpenFileDialog())
                {
                    if (dialog.ShowDialog() == DialogResult.OK)
                    {
                        string filePath = dialog.FileName;
                        using (StreamReader reader = new StreamReader(filePath))
                        {
                            publicKey = reader.ReadToEnd();
                            tbPubKey.Text = publicKey;
                        }
                    }
                }
            }
            catch (Exception)
            {

                MessageBox.Show("配置公钥失败！", "提示");
            }
            
        }


        private void btnSetPrivateKey_Click(object sender, EventArgs e)
        {
            try
            {
                using (OpenFileDialog dialog = new OpenFileDialog())
                {
                    if (dialog.ShowDialog() == DialogResult.OK)
                    {
                        string filePath = dialog.FileName;
                        using (StreamReader reader = new StreamReader(filePath))
                        {
                            privateKey = reader.ReadToEnd();
                            tbPriKey.Text = privateKey;
                        }
                    }
                }
            }
            catch (Exception)
            {
                MessageBox.Show("配置私钥失败！", "提示");

            }
           
        }

        string licence = string.Empty;
        string licPath = string.Empty;
        private void GenLicense_Click(object sender, EventArgs e)
        {
            //生成授权文件需要：机器序列号+私钥+授权时间 
            if (serialNo == string.Empty)
            {
                MessageBox.Show("生成授权文件需要目标机器的序列号！", "提示");
                return;
            }
            if (privateKey == string.Empty)
            {
                MessageBox.Show("生成授权文件需要使用私钥！", "提示");
                return;
            }
            //new DateTimeOffset(DateTime.UtcNow).ToUnixTimeSeconds().ToString();
            long start = new DateTimeOffset(dtpStartTime.Value).ToUnixTimeSeconds();
            long end = new DateTimeOffset(dtpEndTime.Value).ToUnixTimeSeconds();
            if (end <= start)
            {
                MessageBox.Show("授权的终止时间必须大于起始时间！", "提示");
                return;
            }

            string lic = string.Empty;
        
            lic = LicenseTools.LicenseServer.GenLicense(serialNo, privateKey, start, end);
            if (lic==null)
            {
                MessageBox.Show("生成授权文件失败！", "提示");
                return;
            }
              
            try
            {
                using (FolderBrowserDialog dialog = new FolderBrowserDialog())
                {
                    if (dialog.ShowDialog() == DialogResult.OK)
                    {
                        string savePath = dialog.SelectedPath;
                        using (StreamWriter writer = new StreamWriter(Path.Combine(savePath, "License.txt")))
                        {
                            writer.WriteLine(lic);
                        }
                        licPath = Path.Combine(savePath, "License.txt");
                    }
                }
            }
            catch (Exception)
            {
                MessageBox.Show("保存授权文件失败！", "提示");
                return;
            }

            licence = lic;
            tbLic.Text = lic;
        }

        private void btnLicTest_Click(object sender, EventArgs e)
        {
            //授权测试需要 机器序列号+公钥
            if (serialNo == string.Empty)
            {
                MessageBox.Show("授权测试需要目标机器的序列号！", "提示");
                return;
            }
            if (publicKey == string.Empty)
            {
                MessageBox.Show("授权测试需要使用公钥！", "提示");
                return;
            }

            //无论授权是否通过，都更新校验时间
            if (LicenseTools.LicenseClient.VerifyLicense(licence, publicKey) == false)
            {
                LicenseTools.LicenseClient.UpdateVerifyTime(licence, licPath);
                MessageBox.Show("授权文件无效！", "提示");
                
            }
            else
            {
                LicenseTools.LicenseClient.UpdateVerifyTime(licence,licPath);
                MessageBox.Show("授权文件有效！", "提示");
            }
        }

        private void btnSetLic_Click(object sender, EventArgs e)
        {
            try
            {
                using (OpenFileDialog dialog = new OpenFileDialog())
                {
                    if (dialog.ShowDialog() == DialogResult.OK)
                    {
                        string filePath = dialog.FileName;
                        licPath = filePath;
                        using (StreamReader reader = new StreamReader(filePath))
                        {
                            //显示授权码
                            licence = reader.ReadToEnd();
                            tbLic.Text = licence;

                            //显示机器码和时间
                            var strs = LicenseTools.LicenseServer.GetLicenseDetail(licence);
                            if (strs == null)
                                return;

                            try
                            {
                                serialNo = strs[0];
                                tbSN.Text = strs[0];
                                //北京为东8区，比UTC快8小时，转换时要加上这8小时
                                dtpStartTime.Value = new DateTime(1970, 1, 1, 8, 0, 0).AddSeconds(Convert.ToInt64(strs[1]));
                                dtpEndTime.Value = new DateTime(1970, 1, 1, 8, 0, 0).AddSeconds(Convert.ToInt64(strs[2]));
                                dtpLastTime.Value = new DateTime(1970, 1, 1, 8, 0, 0).AddSeconds(Convert.ToInt64(strs[3]));
                            }
                            catch (Exception)
                            {
                                MessageBox.Show("授权文件无效！", "提示");
                            }
                        }
                    }
                }
            }
            catch (Exception)
            {

                MessageBox.Show("加载授权文件失败！", "提示");
            }
          
        }


        private void btnSetSN_Click(object sender, EventArgs e)
        {
            try
            {
                using (OpenFileDialog dialog = new OpenFileDialog())
                {
                    if (dialog.ShowDialog() == DialogResult.OK)
                    {
                        string filePath = dialog.FileName;
                        using (StreamReader reader = new StreamReader(filePath))
                        {
                            serialNo = reader.ReadToEnd();
                            tbSN.Text = serialNo;
                        }
                    }
                }
            }
            catch (Exception)
            {
                MessageBox.Show("加载机器序列号失败！", "提示");

            }
           
        }


        private string[] ShowLicense(string license)
        {
            try
            {
                byte[] lic = Convert.FromBase64String(license);

                //获取加密数据长度
                int dataCnt = BitConverter.ToInt16(lic, 48);

                //获取机器码
                byte[] sn = lic.Skip(0).Take(50 + dataCnt).ToArray();

                //获取时间
                byte[] times = lic.Skip(48 + 2 + dataCnt + 128).ToArray();
                byte[] start = lic.Skip(50 + dataCnt + 128).Take(8).ToArray();
                byte[] end = lic.Skip(50 + dataCnt + 128 + 8).Take(8).ToArray();
                byte[] last = lic.Skip(50 + dataCnt + 128 + 16).Take(8).ToArray();


                //依次返回机器码和三个时间
                return new string[]
                {
                 Convert.ToBase64String(sn),
                 BitConverter.ToInt64(start,0).ToString(),
                 BitConverter.ToInt64(end,0).ToString(),
                 BitConverter.ToInt64(last,0).ToString(),
                };
            }
            catch (Exception)
            {
                 MessageBox.Show("授权文件格式错误！", "提示");
                return null;
            }
       
        }

        private void FrmLicenseGenerator_Load(object sender, EventArgs e)
        {
            dtpStartTime.Value = DateTime.Now;
            dtpEndTime.Value = DateTime.Now;
            dtpLastTime.Value = DateTime.Now;

        }
    }

}
